package com.jinbei.aop;

import com.alibaba.fastjson.JSONObject;
import com.jinbei.common.contants.Contants;
import com.jinbei.common.util.AuthorizationUtil;
import com.jinbei.common.util.CookieUtil;
import com.jinbei.domain.Logs;
import com.jinbei.domain.User;
import com.jinbei.service.LogsService;
import com.jinbei.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author zflu
 * 切面记录操作日志
 * Created by zflu on 2018/7/8.
 */
@Order(4)
@Aspect
@Component
public class AspectLogger {

    private final Logger logger = LoggerFactory.getLogger(AspectLogger.class);
    
    @Autowired
    private LogsService logsService;

    @Autowired
    private UserService userService;

    /**
     * @Author zflu
     * @Description 定义一个切面
     * @Date 2018/7/8 1:50
     * @Param []
     * @return void
     **/
    @Pointcut("execution(* com.jinbei.restController.*.*(..))")
    public void pointCutController(){
    }

    /**
     * @Author zflu
     * @Description 环绕通知
     * @Date 2018/7/8 1:58
     * @Param [point]
     * @return void
     **/
    @Around(value = "pointCutController()")
    public Object recordLogging(ProceedingJoinPoint  point) throws Throwable {
        return point.proceed();
    }

    /**
     * @Author zflu
     * @Description 前置通知打印日志
     * @Date 2018/7/8 10:13
     * @Param []
     * @return void
     **/
    @Before(value = "pointCutController()")
    public void methodBeforeReturning(JoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        if(logger.isDebugEnabled()){
            logger.debug("-------request print start-------");
            try {
                logger.debug("request url : {}",request.getRequestURI().toString());
                logger.debug("request ip : {}",request.getRemoteAddr());
                logger.debug("request method : {}",request.getMethod());
                logger.debug("request params :{}", Arrays.toString(joinPoint.getArgs()));
            }catch (Exception e){
                logger.error("###AspectLogger.class methodBefore() ### ERROR:", e);
            }
            logger.debug("-------request print end-------");
            logger.debug("");
        }
    }

    /**
     * @Author zflu
     * @Description 后置通知打印日志
     * @Date 2018/7/8 10:25
     * @Param [o]
     * @return void
     **/
    @AfterReturning(returning = "o", pointcut = "pointCutController()")
    public void methodAfterReturning(Object o) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            //获取日志
            String attribute = (String) request.getAttribute(Contants.LOGS);
            if(StringUtils.isBlank(attribute)){
                return ;
            }
            //获取授权code
            String code = CookieUtil.getCookie(request,Contants.AUTHORIZATION);
            if(StringUtils.isBlank(code)){
                return ;
            }
            JSONObject json = AuthorizationUtil.getUserByAuthorization(code);
            //授权失败
            if(json.isEmpty()){
                return ;
            }
            String loginName = (String) json.get(Contants.LOGIN_NAME);

            if(StringUtils.isNotBlank(loginName)){
                User user = userService.queryUserByLoginName(loginName);
                Logs logs = new Logs();
                logs.setUserId(user.getUserId());
                logs.setLoginName(loginName);
                logs.setIp(request.getRemoteAddr());
                logs.setLogger(attribute);
                logs.setUserName(user.getUserName());
                //存当前操作的日志
                logsService.insertLogs(logs);
            }
            if(logger.isDebugEnabled()){
                logger.debug("-------response print start-------");
                logger.debug("日志为: "+attribute);
                logger.debug("Response内容:" + JSONObject.toJSONString(o));
                logger.debug("-------response print end-------");
                logger.debug("");
            }
        } catch (Exception e) {
            logger.error("###AspectLogger.class methodAfterReturning() ### ERROR:", e);
        }
    }

}
